<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=2"><meta name="theme-color" content="#222"><meta name="generator" content="Hexo 5.4.0"><link rel="apple-touch-icon" sizes="180x180" href="/blog/images/avatar32.png"><link rel="icon" type="image/png" sizes="32x32" href="/blog/images/avatar32.png"><link rel="icon" type="image/png" sizes="16x16" href="/blog/images/avatar32.png"><link rel="mask-icon" href="/blog/images/avatar.ico" color="#222"><link rel="stylesheet" href="/blog/css/main.css"><link rel="stylesheet" href="//fonts.loli.net/css?family=EB Garamond:300,300italic,400,400italic,700,700italic|Cinzel Decorative:300,300italic,400,400italic,700,700italic|Source Code Pro:300,300italic,400,400italic,700,700italic&display=swap&subset=latin,latin-ext"><link rel="stylesheet" href="/blog/lib/font-awesome/css/font-awesome.min.css"><link rel="stylesheet" href="//cdn.jsdelivr.net/npm/pace-js@1/themes/blue/pace-theme-minimal.css"><script src="//cdn.jsdelivr.net/npm/pace-js@1/pace.min.js"></script><script id="hexo-configurations">var NexT=window.NexT||{},CONFIG={root:"/blog/",scheme:"Muse",version:"7.8.0",exturl:!1,sidebar:{position:"right",width:200,display:"post",padding:18,offset:12,onmobile:!1},copycode:{enable:!0,show_result:!1,style:"default"},back2top:{enable:!0,sidebar:!0,scrollpercent:!0},bookmark:{enable:!1,color:"#222",save:"auto"},fancybox:!1,mediumzoom:!0,lazyload:!1,pangu:!1,algolia:{appID:"",apiKey:"",indexName:"",hits:{per_page:10},labels:{input_placeholder:"Search for Posts",hits_empty:"We didn't find any results for the search: ${query}",hits_stats:"${hits} results found in ${time} ms"}},localsearch:{enable:!0,trigger:"auto",top_n_per_article:1,unescape:!1,preload:!1},path:"search.xml",motion:{enable:!0,async:!1,transition:{post_block:"fadeIn",post_header:"slideDownIn",post_body:"slideDownIn",coll_header:"slideLeftIn",sidebar:"slideRightIn"}},sidebarPadding:40}</script><script data-ad-client="ca-pub-1414767122267457" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><meta name="description" content="9.1 什么是 Virtrual DomVirtual Dom 是基于 JavaScript 计算的，在状态发生变化时，Virtual Dom 会进行 Diff 运算。 正常的 DOM 节点在 HTML 中： 1234&lt;div id&#x3D;&quot;main&quot;&gt;    &lt;p&gt;文本内容&lt;&#x2F;p&gt;&lt;&#x2F;div&gt;    &lt;p&gt;文本内容&lt;"><meta property="og:type" content="article"><meta property="og:title" content="9.Render函数"><meta property="og:url" content="https://linxiaoki.gitee.io/blog/categories/%E5%89%8D%E7%AB%AF/%E3%80%8AVue-js-%E5%AE%9E%E6%88%98%E3%80%8B%E7%AC%94%E8%AE%B0/9-render%E5%87%BD%E6%95%B0/index.html"><meta property="og:site_name" content="人间且慢行"><meta property="og:description" content="9.1 什么是 Virtrual DomVirtual Dom 是基于 JavaScript 计算的，在状态发生变化时，Virtual Dom 会进行 Diff 运算。 正常的 DOM 节点在 HTML 中： 1234&lt;div id&#x3D;&quot;main&quot;&gt;    &lt;p&gt;文本内容&lt;&#x2F;p&gt;&lt;&#x2F;div&gt;    &lt;p&gt;文本内容&lt;"><meta property="og:locale" content="zh_CN"><meta property="og:image" content="https://tva3.sinaimg.cn/large/005zbIM7ly1g5vtpdwp17j30ii06u786.jpg"><meta property="article:published_time" content="2019-08-11T00:00:00.000Z"><meta property="article:modified_time" content="2019-11-26T00:00:00.000Z"><meta property="article:author" content="我的名字"><meta property="article:tag" content="Web"><meta property="article:tag" content="Vue"><meta name="twitter:card" content="summary"><meta name="twitter:image" content="https://tva3.sinaimg.cn/large/005zbIM7ly1g5vtpdwp17j30ii06u786.jpg"><link rel="canonical" href="https://linxiaoki.gitee.io/blog/categories/%E5%89%8D%E7%AB%AF/%E3%80%8AVue-js-%E5%AE%9E%E6%88%98%E3%80%8B%E7%AC%94%E8%AE%B0/9-render%E5%87%BD%E6%95%B0/"><script id="page-configurations">CONFIG.page={sidebar:"",isHome:!1,isPost:!0,lang:"zh-CN"}</script><link href="https://fonts.loli.net/css?family=Noto+Serif+SC:400,500,700&display=swap&subset=chinese-simplified" rel="stylesheet"><link href="https://fonts.loli.net/css?family=EB+Garamond:400,500,700&display=swap" rel="stylesheet"><link href="https://fonts.loli.net/css?family=Cinzel+Decorative&display=swap" rel="stylesheet"><link href="https://fonts.loli.net/css?family=Source+Code+Pro&display=swap" rel="stylesheet"><title>9.Render函数 | 人间且慢行</title><script async src="https://www.googletagmanager.com/gtag/js?id=UA-168149316-1"></script><script data-pjax>function gtag(){dataLayer.push(arguments)}CONFIG.hostname===location.hostname&&(window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","UA-168149316-1"))</script><noscript><style>.sidebar-inner,.use-motion .brand,.use-motion .collection-header,.use-motion .comments,.use-motion .menu-item,.use-motion .pagination,.use-motion .post-block,.use-motion .post-body,.use-motion .post-header{opacity:initial}.use-motion .site-subtitle,.use-motion .site-title{opacity:initial;top:initial}.use-motion .logo-line-before i{left:initial}.use-motion .logo-line-after i{right:initial}</style></noscript></head><body itemscope itemtype="http://schema.org/WebPage"><div class="container use-motion"><div class="headband"></div><header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="header-inner"><div class="site-brand-container"><div class="site-nav-toggle"><div class="toggle" aria-label="切换导航栏"><span class="toggle-line toggle-line-first"></span> <span class="toggle-line toggle-line-middle"></span> <span class="toggle-line toggle-line-last"></span></div></div><div class="site-meta"><a href="/blog/" class="brand" rel="start"><span class="logo-line-before"><i></i></span><h1 class="site-title">人间且慢行</h1><span class="logo-line-after"><i></i></span></a></div><div class="site-nav-right"><div class="toggle popup-trigger"><i class="fa fa-search fa-fw fa-lg"></i></div></div></div><nav class="site-nav"><ul id="menu" class="menu"><li class="menu-item menu-item-home"><a href="/blog/" rel="section"><i class="fa fa-fw fa-home"></i>首页</a></li><li class="menu-item menu-item-tags"><a href="/blog/tags/" rel="section"><i class="fa fa-fw fa-tags"></i>标签</a></li><li class="menu-item menu-item-categories"><a href="/blog/categories/" rel="section"><i class="fa fa-fw fa-th"></i>分类</a></li><li class="menu-item menu-item-archives"><a href="/blog/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>归档</a></li><li class="menu-item menu-item-search"><a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索</a></li></ul></nav><div class="search-pop-overlay"><div class="popup search-popup"><div class="search-header"><span class="search-icon"><i class="fa fa-search"></i></span><div class="search-input-container"><input autocomplete="off" autocapitalize="off" placeholder="搜索..." spellcheck="false" type="search" class="search-input"></div><span class="popup-btn-close"><i class="fa fa-times-circle"></i></span></div><div id="search-result"><div id="no-result"><i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i></div></div></div></div></div></header><a href="https://github.com/linxiaoki" class="github-corner" title="Follow me on GitHub" aria-label="Follow me on GitHub" rel="noopener" target="_blank"><svg style="fill:#008b8b" width="80" height="80" viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin:130px 106px" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><main class="main"><div class="main-inner"><div class="content-wrap"><div class="content post posts-expand"><article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN"><link itemprop="mainEntityOfPage" href="https://linxiaoki.gitee.io/blog/categories/%E5%89%8D%E7%AB%AF/%E3%80%8AVue-js-%E5%AE%9E%E6%88%98%E3%80%8B%E7%AC%94%E8%AE%B0/9-render%E5%87%BD%E6%95%B0/"><span hidden itemprop="author" itemscope itemtype="http://schema.org/Person"><meta itemprop="image" content="/blog/images/avatar.gif"><meta itemprop="name" content="我的名字"><meta itemprop="description" content="一起滚月球吧·"></span><span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization"><meta itemprop="name" content="人间且慢行"></span><header class="post-header"><h1 class="post-title" itemprop="name headline">9.Render函数</h1><div class="post-meta"><span class="post-meta-item"><span class="post-meta-item-icon"><i class="fa fa-calendar-o"></i> </span><span class="post-meta-item-text">发表于</span> <time title="创建时间：2019/08/11 00:00:00" itemprop="dateCreated datePublished" datetime="2019-08-11T00:00:00+00:00">2019/08/11</time> </span><span class="post-meta-item"><span class="post-meta-item-icon"><i class="fa fa-calendar-check-o"></i> </span><span class="post-meta-item-text">更新于</span> <time title="修改时间：2019/11/26 00:00:00" itemprop="dateModified" datetime="2019-11-26T00:00:00+00:00">2019/11/26</time> </span><span class="post-meta-item"><span class="post-meta-item-icon"><i class="fa fa-folder-o"></i> </span><span class="post-meta-item-text"></span> <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/blog/categories/%E5%89%8D%E7%AB%AF/" itemprop="url" rel="index"><span itemprop="name">前端</span></a> </span>, <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/blog/categories/%E5%89%8D%E7%AB%AF/%E3%80%8AVue-js-%E5%AE%9E%E6%88%98%E3%80%8B%E7%AC%94%E8%AE%B0/" itemprop="url" rel="index"><span itemprop="name">《Vue.js 实战》笔记</span></a></span></span><br><span class="post-meta-item" title="本文字数"><span class="post-meta-item-icon"><i class="fa fa-file-word-o"></i> </span><span class="post-meta-item-text">本文字数：</span> <span>8.1k</span> </span><span class="post-meta-item" title="阅读时长"><span class="post-meta-item-icon"><i class="fa fa-clock-o"></i> </span><span class="post-meta-item-text">阅读时长 &asymp;</span> <span>7 分钟</span></span></div></header><div class="post-body" itemprop="articleBody"><h4 id="9-1-什么是-Virtrual-Dom"><a href="#9-1-什么是-Virtrual-Dom" class="headerlink" title="9.1 什么是 Virtrual Dom"></a>9.1 什么是 Virtrual Dom</h4><p>Virtual Dom 是基于 JavaScript 计算的，在状态发生变化时，Virtual Dom 会进行 Diff 运算。<br><img src="//tva3.sinaimg.cn/large/005zbIM7ly1g5vtpdwp17j30ii06u786.jpg" alt="img"></p><p>正常的 DOM 节点在 HTML 中：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;main&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span>&gt;</span>文本内容<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span>&gt;</span>文本内容<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br></pre></td></tr></table></figure><p>用 Virtual Dom 创建的 JavaScript 对象一般会是这样的：</p><figure class="highlight gml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> vNode = &#123;</span><br><span class="line">    tag: <span class="string">&#x27;div&#x27;</span>,</span><br><span class="line">    attributes:&#123;</span><br><span class="line">        <span class="symbol">id</span>: <span class="string">&#x27;main&#x27;</span></span><br><span class="line">    &#125;,</span><br><span class="line">    children:&#123;</span><br><span class="line">        <span class="comment">//p 节点</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><span id="more"></span><p>Virtual Dom 就是通过一种 VNode 类表达的，每个 DOM 元素或组件都对应一<br>个 VNode 对象。(关键字: <code>tag,data,childred,text...</code>)</p><p><strong>VNode 主要分为如下几类：</strong></p><ul><li>TextVNode 文本节点</li><li>ElementVNode 普通元素节点</li><li>ComponentVNode 组件节点</li><li>EmptyVNode 没有内容的注释节点</li><li>CloneVNode 克隆节点，可以是以上任意类型的节点，唯一的区别在于 isCloned 属性为 true 。</li></ul><p>多数场景使用 template 就足够，但在一些特定的场景下，使用 Virtual Dom 会更简单。</p><h4 id="9-2-什么是-Render-函数"><a href="#9-2-什么是-Render-函数" class="headerlink" title="9.2 什么是 Render 函数"></a>9.2 什么是 Render 函数</h4><h5 id="实现锚点标签"><a href="#实现锚点标签" class="headerlink" title="实现锚点标签"></a>实现锚点标签</h5><ul><li><p>使用 template 实现</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">div#app</span><br><span class="line">    anchor[level=&quot;2&quot;][title=&quot;特性&quot;]&#123;特性&#125;</span><br><span class="line">    </span><br><span class="line">script[text/x-template][id=&quot;anchor&quot;]</span><br><span class="line">    div</span><br><span class="line">        (h$[v-if=&quot;level===$&quot;][:id=&quot;title&quot;]&gt;a[:href=&quot;&#x27;#&#x27;+title&quot;]&gt;slot )*6</span><br><span class="line"></span><br><span class="line">script</span><br><span class="line">    Vue.component(&quot;anchor&quot;,&#123;</span><br><span class="line">        props:&#123;</span><br><span class="line">            title:&#123;</span><br><span class="line">                type:String,</span><br><span class="line">                default:&#x27;&#x27;</span><br><span class="line">            &#125;,</span><br><span class="line">            level:&#123;</span><br><span class="line">                type:Number,</span><br><span class="line">                required:true</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    </span><br><span class="line">    var app = new Vue(&#123;</span><br><span class="line">        el:&#x27;#app&#x27;</span><br><span class="line">    &#125;)</span><br></pre></td></tr></table></figure></li><li><p>使用 Render 实现</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">div#app</span><br><span class="line">    anchor[level=&quot;2&quot;][title=&quot;特性&quot;]&#123;特性&#125;</span><br><span class="line">script</span><br><span class="line">    Vue.component(&#x27;anchor&#x27;,&#123;</span><br><span class="line">        props:&#123;</span><br><span class="line">            level:&#123;</span><br><span class="line">                type:Number,</span><br><span class="line">                required:true</span><br><span class="line">            &#125;,</span><br><span class="line">            title:&#123;</span><br><span class="line">                type:String,</span><br><span class="line">                default:&#x27;&#x27;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;,</span><br><span class="line">        render:funciton(createElement)&#123;</span><br><span class="line">            return createElement(</span><br><span class="line">                &#x27;h&#x27;+this.level,</span><br><span class="line">                &#123;</span><br><span class="line">                    attrs:&#123;</span><br><span class="line">                        id:this.title</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;,</span><br><span class="line">                [</span><br><span class="line">                    createElement(</span><br><span class="line">                        &#x27;a&#x27;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            domProps:&#123;</span><br><span class="line">                                href:&#x27;#&#x27;+this.title</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;,</span><br><span class="line">                        this.$slots.default</span><br><span class="line">                    )</span><br><span class="line">                ]</span><br><span class="line">            )</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br></pre></td></tr></table></figure></li></ul><h4 id="9-3-reateElement-用法"><a href="#9-3-reateElement-用法" class="headerlink" title="9.3 reateElement 用法"></a>9.3 reateElement 用法</h4><h5 id="9-3-1-基本参数"><a href="#9-3-1-基本参数" class="headerlink" title="9.3.1 基本参数"></a>9.3.1 基本参数</h5><p>createElement 构成了 Vue Virtual Dom 的模板，它有 3 个参数：</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br></pre></td><td class="code"><pre><span class="line">createElement(</span><br><span class="line">    <span class="regexp">//</span> &#123;String | Object | Function)</span><br><span class="line">    <span class="regexp">//</span>一个 HTML 标签，组件选项，或一个函数</span><br><span class="line">    <span class="regexp">//</span>必须 Return 上述其中一个</span><br><span class="line">    <span class="string">&#x27;div&#x27;</span>,</span><br><span class="line">    </span><br><span class="line">    <span class="regexp">//</span>&#123;Object&#125;</span><br><span class="line">    <span class="regexp">//</span> 一个对应属性的数据对象，可选</span><br><span class="line">    <span class="regexp">//</span>可以在 template 中使用</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="regexp">//</span>和 v-bind:class 一样的 API</span><br><span class="line">        class:&#123;</span><br><span class="line">            foo : true ,</span><br><span class="line">            bar: false</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="regexp">//</span>和 v-bind:style 一样的 API</span><br><span class="line">        style : &#123;</span><br><span class="line">            color:<span class="string">&#x27;red&#x27;</span>,</span><br><span class="line">            fontSize:<span class="string">&#x27;14px&#x27;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="regexp">//</span>正常的 HTML 特性</span><br><span class="line">        attrs: &#123;</span><br><span class="line">            id:<span class="string">&#x27;foo&#x27;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="regexp">//</span>组件 props</span><br><span class="line">        props: &#123;</span><br><span class="line">            myProp : <span class="string">&#x27;bar&#x27;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="regexp">//</span>DOM 属性</span><br><span class="line">        domProps: &#123;</span><br><span class="line">            InnerHTML ：<span class="string">&#x27;baz&#x27;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="regexp">//</span>自定义事件监听器<span class="string">&quot;on&quot;</span></span><br><span class="line">        <span class="regexp">//</span>不支持如 v-on:keyup.enter 的修饰器</span><br><span class="line">        <span class="regexp">//</span>需要手动匹配 keyCode</span><br><span class="line">        on: &#123;</span><br><span class="line">            click: this.clickHandler</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="regexp">//</span>仅对于组件，用于监听原生事件</span><br><span class="line">        <span class="regexp">//</span>而不是组件使用 vm.<span class="variable">$emit</span> 触发的自定义事件</span><br><span class="line">        nativeOn: &#123;</span><br><span class="line">            click: this.nativeClickHandler</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="regexp">//</span>自定义指令</span><br><span class="line">        directives: [</span><br><span class="line">            name:<span class="string">&#x27;my-custom-directive&#x27;</span>,</span><br><span class="line">            value:<span class="string">&#x27;2&#x27;</span></span><br><span class="line">            expression:<span class="string">&#x27;1 + 1&#x27;</span>,</span><br><span class="line">            arg : <span class="string">&#x27;foo&#x27;</span>,</span><br><span class="line">            modifiers : &#123;</span><br><span class="line">                bar: true</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="regexp">//</span>作用域 slot</span><br><span class="line">        <span class="regexp">//</span>&#123; name: props =&gt; VNode | Array&lt;VNode&gt; &#125;</span><br><span class="line">        scopedSlots: &#123;</span><br><span class="line">            default: props =&gt; h(<span class="string">&#x27;span&#x27;</span>, props text)</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="regexp">//</span>如果子组件有定义 slot 的名称</span><br><span class="line">        slot:<span class="string">&#x27;name-of-slot&#x27;</span></span><br><span class="line">        <span class="regexp">//</span>其他特殊顶层属性</span><br><span class="line">        key: <span class="string">&#x27;myKey&#x27;</span>,</span><br><span class="line">        ref: <span class="string">&#x27;myRef&#x27;</span></span><br><span class="line">    &#125;,</span><br><span class="line">    </span><br><span class="line">    <span class="regexp">//</span> &#123;String | Array)</span><br><span class="line">    <span class="regexp">//</span> 子节点（ VNodes ），可选</span><br><span class="line">    [</span><br><span class="line">        createElement ( <span class="string">&#x27;h1&#x27;</span>,<span class="string">&#x27;hello world&#x27;</span>),</span><br><span class="line">        createElement(MyComponent, &#123;</span><br><span class="line">            props : &#123;</span><br><span class="line">                someProp:<span class="string">&#x27;foo&#x27;</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;),</span><br><span class="line">        <span class="string">&#x27;bar&#x27;</span></span><br><span class="line">    ]</span><br><span class="line">)</span><br></pre></td></tr></table></figure><p>第一个参数必选，可以是一个 HTML 标签，也可以是一个组件或函数；第二个是可选参数，数据对象，在 template 中使用。第三个是子节点，也是可选参数，用法一致。</p><h5 id="9-3-2-约束"><a href="#9-3-2-约束" class="headerlink" title="9.3.2 约束"></a>9.3.2 约束</h5><p>所有组件树中，如果 VNode 是组件或含有组件的 slot ，那么 VNode 必须唯一。<br><br><strong>错误的写法:</strong><br></p><ol><li>重复使用组件<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">script</span><br><span class="line">    <span class="comment">//局部声明组件</span></span><br><span class="line">    <span class="keyword">var</span> Child=&#123;</span><br><span class="line">        <span class="attr">render</span>:<span class="function"><span class="keyword">function</span>(<span class="params">createElement</span>)</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> createElement(<span class="string">&#x27;p&#x27;</span>,<span class="string">&#x27;text&#x27;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    Vue.component(<span class="string">&#x27;ele&#x27;</span>,&#123;</span><br><span class="line">        <span class="attr">render</span>:<span class="function"><span class="keyword">function</span>(<span class="params">createElemnt</span>)</span>&#123;</span><br><span class="line">            <span class="comment">//使用组件 Child, 创建一个子节点</span></span><br><span class="line">            <span class="keyword">var</span> ChildNode=createElement(Child);</span><br><span class="line">            <span class="keyword">return</span> createElement(<span class="string">&#x27;div&#x27;</span>,[</span><br><span class="line">                ChildNode,</span><br><span class="line">                ChildNode</span><br><span class="line">            ])</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line"><span class="comment">//-----</span></span><br><span class="line"><span class="comment">//改</span></span><br><span class="line"><span class="built_in">Array</span>.apply(<span class="literal">null</span>,&#123;<span class="attr">length</span>:<span class="number">2</span>&#125;).map(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> createElement(Child)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure></li><li>重复使用含有组件的 slot<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">&lt;-    div#app&gt;ele&gt;div&gt;Child    -&gt;</span><br><span class="line"><span class="comment">//全局注册组件</span></span><br><span class="line">Vue.component(<span class="string">&#x27;Child&#x27;</span>,&#123;</span><br><span class="line">    <span class="attr">render</span>:<span class="function"><span class="keyword">function</span>(<span class="params">createElement&#123;</span></span></span><br><span class="line"><span class="params"><span class="function">        <span class="keyword">return</span> createElement(<span class="string">&#x27;p&#x27;</span>,<span class="string">&#x27;text&#x27;</span>);</span></span></span><br><span class="line"><span class="params"><span class="function">    &#125;</span></span></span><br><span class="line"><span class="params"><span class="function">&#125;</span>)</span>;</span><br><span class="line"></span><br><span class="line">Vue.component(<span class="string">&#x27;ele&#x27;</span>,&#123;</span><br><span class="line">    <span class="attr">render</span>:<span class="function"><span class="keyword">function</span>(<span class="params">createElement</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> createElement(<span class="string">&#x27;div&#x27;</span>,&#123;</span><br><span class="line">            <span class="built_in">this</span>.$slots.default,</span><br><span class="line">            <span class="built_in">this</span>.$slots.default</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br></pre></td></tr></table></figure>上面两个例子中的两个 <code>Child</code> 组件都只能渲染出一个，<code>VNode</code>受到了约束。</li></ol><p>如何重复使用组件，或含有组件的 slot。</p><p><em>代码在文件夹 9.3.2 约束 中</em></p><p>通过一个循环和工厂函数可以渲染5个重复的子组件 Child。 <strong>p145</strong><br>深度克隆子节点</p><h5 id="9-3-3-使用-JavaScript-代替模板功能"><a href="#9-3-3-使用-JavaScript-代替模板功能" class="headerlink" title="9.3.3 使用 JavaScript 代替模板功能"></a>9.3.3 使用 JavaScript 代替模板功能</h5><p>在 Render 函数中，不能使用 Vue 内置的指令，所以可以用原生的 JavaScript 实现。</p><ul><li><code>v-if | v-else</code></li><li><code>v-for</code></li><li><code>map</code></li><li><code>v-model</code></li><li><code>修饰符</code></li></ul><table><thead><tr><th>修饰符</th><th>对应的句柄</th></tr></thead><tbody><tr><td><code>.stop</code></td><td><code>event.stopPropagation()</code></td></tr><tr><td><code>.prevent</code></td><td><code>event.preventDefault()</code></td></tr><tr><td><code>.self</code></td><td><code>if(event.target!==event.currentTarget) return</code></td></tr><tr><td><code>.enter、.13</code></td><td><code>if(event.keyCode!==13) return</code> 替换 13 位需要的 <code>keyCode</code></td></tr><tr><td><code>.ctrl、.alt、.shift、.meta</code></td><td><code>if(!event.ctrlKey) return</code> 根据需要替换 <code>ctrlKey</code> 为 <code>altKey</code>、<code>shiftKey</code> 或 <code>metaKey</code>。</td></tr></tbody></table><table><thead><tr><th>修饰符</th><th>特殊的前缀(写在 on 里)</th></tr></thead><tbody><tr><td><code>.capture</code></td><td>!</td></tr><tr><td><code>.once</code></td><td>~</td></tr><tr><td><code>.capture.once</code> 或 <code>.once.capture</code></td><td>~!</td></tr></tbody></table><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//写在 on 前</span></span><br><span class="line"><span class="attr">on</span>: &#123;</span><br><span class="line">    <span class="string">&#x27;!click&#x27;</span>: <span class="built_in">this</span>.doThisInCapturingMode,</span><br><span class="line">    <span class="string">&#x27;~keyup&#x27;</span>: <span class="built_in">this</span>.doThisOnce,</span><br><span class="line">    <span class="string">&#x27;~!mouseover&#x27;</span>:<span class="built_in">this</span>.doThisOnceInCapturingMode</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li><code>slot</code></li></ul><h4 id="9-4-函数化组件"><a href="#9-4-函数化组件" class="headerlink" title="9.4 函数化组件"></a>9.4 函数化组件</h4><p>作用：减少开销渲染<br>做法：Render 提供两个参数：</p><ul><li><code>function</code>参数，值为<code>true</code>,使组件无状态和无实例（没有 <code>data</code> <code>this</code> 上下文），这样 render 函数返回的虚拟节点更容易渲染。<br></li><li><code>context</code>参数，提供临时上下文，组件需要的 <code>data</code>、<code>props</code>、<code>slots</code>、<code>children</code>、<code>parent</code> 都是通过这个上下文来传递。（比如：<code>this.level =&gt; contex.props.level</code>）</li></ul><p><strong>根据 button 选择不同组件的场景</strong></p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">div#app</span><br><span class="line">    smart-item[:data=&quot;data&quot;]</span><br><span class="line">    (button[@click=&quot;img|video|text&quot;]&#123;切换为。。&#125;) *3</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> ImgItem=&#123;</span><br><span class="line">    <span class="attr">props</span>:[<span class="string">&#x27;data&#x27;</span>],</span><br><span class="line">    <span class="attr">render</span>:<span class="function"><span class="keyword">function</span>(<span class="params">createElement</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> createElement(<span class="string">&#x27;div&#x27;</span>,[</span><br><span class="line">            createElement(<span class="string">&#x27;p&#x27;</span>,<span class="string">&#x27;图片组件&#x27;</span>),</span><br><span class="line">            createElement(<span class="string">&#x27;img&#x27;</span>,&#123;</span><br><span class="line">                <span class="attr">attrs</span>:&#123;</span><br><span class="line">                    <span class="attr">src</span>:<span class="built_in">this</span>.data.url</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;)</span><br><span class="line">        ])</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> VideoItem=&#123;</span><br><span class="line">    <span class="attr">props</span>:[...],</span><br><span class="line">    <span class="attr">render</span>:<span class="function"><span class="keyword">function</span>(<span class="params">createElement</span>)</span>&#123;</span><br><span class="line">        ...</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> TextItem=&#123;</span><br><span class="line">    <span class="comment">//这个 data_____  要和 component 的 data_____ 一样</span></span><br><span class="line">    <span class="attr">props</span>:[<span class="string">&#x27;data_____&#x27;</span>],</span><br><span class="line">    <span class="attr">render</span>:<span class="function"><span class="keyword">function</span>(<span class="params">createElement</span>)</span>&#123;</span><br><span class="line">        ...</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">Vue.component(<span class="string">&#x27;smart-item&#x27;</span>,&#123;</span><br><span class="line">    <span class="attr">functional</span>:<span class="literal">true</span>,</span><br><span class="line">    <span class="attr">render</span>:<span class="function"><span class="keyword">function</span>(<span class="params">createElement,context</span>)</span>&#123;</span><br><span class="line">        <span class="function"><span class="keyword">function</span> <span class="title">getComponent</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            <span class="comment">//根据 context.props.data </span></span><br><span class="line">            <span class="keyword">if</span> (...)  <span class="keyword">return</span> ...Item</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="function"><span class="title">createElement</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            getComponent(),</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="attr">props</span>:&#123;</span><br><span class="line">                    <span class="comment">//把 smart-item 的 prop：data 传给上面只能选择的组件</span></span><br><span class="line">                    <span class="attr">data_____</span>: context.props.data</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            context.children</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> app=Vue(&#123;</span><br><span class="line">    <span class="attr">el</span>:<span class="string">&#x27;#app&#x27;</span>,</span><br><span class="line">    <span class="attr">data</span>:&#123;</span><br><span class="line">        <span class="attr">data</span>:&#123;&#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">methods</span>:&#123;</span><br><span class="line">        <span class="function"><span class="title">change</span>(<span class="params">type</span>)</span>&#123;</span><br><span class="line">            type==&gt;data:&#123;<span class="attr">type</span>:<span class="string">&#x27;...&#x27;</span>,url|content:<span class="string">&#x27;...&#x27;</span>&#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><p><code>app</code>定义了<code>data</code>=&gt;传给了组件<code>smart-item</code>=&gt;三个对象都接收一个 <code>prop: data</code><br><br>函数化组件不常用，上例可以用组件的 is 特性来动态挂载。函数化组件主要适用于以下两个场景：</p><ul><li>程序化的在多个组件中选择一个</li><li>在将 children，props，data 传递给子组件之前操作它们</li></ul><h4 id="9-5-JavaScript-的语法扩展：JSX"><a href="#9-5-JavaScript-的语法扩展：JSX" class="headerlink" title="9.5 JavaScript 的语法扩展：JSX"></a>9.5 JavaScript 的语法扩展：JSX</h4><p>在模板比较简单时使用 Render 函数写起来会比较麻烦。解决：提供 插件<code>babel-plugin-transroe-vue-jsx</code>来支持 JSX 语法。<br><br><strong>比较：</strong></p><ul><li>template<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">Anchor</span> <span class="attr">:level</span>=<span class="string">&quot;1&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">span</span>&gt;</span>一级<span class="tag">&lt;/<span class="name">span</span>&gt;</span>标题</span><br><span class="line"><span class="tag">&lt;/<span class="name">Anchor</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li>Render -&gt; createElement 改写<figure class="highlight vim"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">return</span> createElement(<span class="string">&#x27;Anchor&#x27;</span>,&#123;</span><br><span class="line">    prop<span class="variable">s:</span>&#123;</span><br><span class="line">        leve<span class="variable">l:1</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;,[</span><br><span class="line">    createElement(<span class="string">&#x27;span&#x27;</span>,<span class="string">&#x27;一级&#x27;</span>),</span><br><span class="line">    <span class="string">&#x27;标题&#x27;</span></span><br><span class="line">])</span><br></pre></td></tr></table></figure></li><li>Render -&gt; 使用 JSX 语法<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//  需要在 webpack 里配置插件 bebel-plugin-tranform-vue-jsx 编译</span></span><br><span class="line"><span class="comment">//  参数 h 不能省略，否则使用时会触发错误</span></span><br><span class="line">    <span class="keyword">new</span> Vue(&#123;</span><br><span class="line">        <span class="attr">el</span>:<span class="string">&#x27;#app&#x27;</span>,</span><br><span class="line">        <span class="function"><span class="title">render</span>(<span class="params">h</span>)</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> (</span><br><span class="line">                <span class="xml"><span class="tag">&lt;<span class="name">Anchor</span> <span class="attr">level</span>=<span class="string">&#123;1&#125;</span>&gt;</span></span></span><br><span class="line"><span class="xml">                    <span class="tag">&lt;<span class="name">span</span>&gt;</span>一级<span class="tag">&lt;/<span class="name">span</span>&gt;</span>标题</span></span><br><span class="line"><span class="xml">                <span class="tag">&lt;/<span class="name">Anchor</span>&gt;</span></span></span><br><span class="line">            )</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br></pre></td></tr></table></figure></li><li>使用 <code>createElement</code> 常用配置<ul><li>正常实现<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">render(createElement)&#123;</span><br><span class="line">    <span class="keyword">return</span> createElement(<span class="string">&#x27;div&#x27;</span>,&#123;</span><br><span class="line">        props:&#123;</span><br><span class="line">            text:<span class="string">&#x27;some text&#x27;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        attrs:&#123;</span><br><span class="line">            <span class="keyword">is</span>:<span class="string">&#x27;myDiv&#x27;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        domProps:&#123;</span><br><span class="line">            innerHTML:<span class="string">&#x27;content&#x27;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        on:&#123;</span><br><span class="line">            change:<span class="keyword">this</span>.changeHandler</span><br><span class="line">        &#125;,</span><br><span class="line">        nativeOn:&#123;</span><br><span class="line">            click:<span class="keyword">this</span>.clickHandler</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="class"><span class="keyword">class</span>:<span class="type">&#123;</span></span></span><br><span class="line">            show:<span class="literal">true</span>,</span><br><span class="line">            on:<span class="literal">false</span></span><br><span class="line">        &#125;,</span><br><span class="line">        style:&#123;</span><br><span class="line">            color:<span class="string">&#x27;#fff&#x27;</span>,</span><br><span class="line">            background:<span class="string">&#x27;#f50&#x27;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        key:<span class="string">&#x27;key&#x27;</span>,</span><br><span class="line">        ref:<span class="string">&#x27;element&#x27;</span>,</span><br><span class="line">        refInFor:<span class="literal">true</span>,</span><br><span class="line">        slot:<span class="string">&#x27;slot&#x27;</span></span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li>使用 JSX<figure class="highlight handlebars"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="xml">render(h)&#123;</span></span><br><span class="line"><span class="xml">    return (</span></span><br><span class="line"><span class="xml">      <span class="tag">&lt;<span class="name">div</span></span></span></span><br><span class="line"><span class="tag"><span class="xml">          <span class="attr">id</span>=<span class="string">&quot;myDiv&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="xml">          <span class="attr">domPropsInnerHTML</span>=<span class="string">&quot;content&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="xml">          <span class="attr">onChange</span>=<span class="string">&#123;this.clickHandler&#125;</span></span></span></span><br><span class="line"><span class="tag"><span class="xml">          <span class="attr">nativeOnClick</span>=<span class="string">&#123;this.clickHandler&#125;</span></span></span></span><br><span class="line"><span class="tag"><span class="xml">          <span class="attr">class</span>=</span></span><span class="template-variable">&#123;&#123;<span class="name">show:true</span>,on:<span class="literal">false</span>&#125;&#125;</span><span class="xml"><span class="tag"></span></span></span><br><span class="line"><span class="tag"><span class="xml">          <span class="attr">style</span>=</span></span><span class="template-variable">&#123;&#123;<span class="name">color:</span><span class="string">&#x27;#fff&#x27;</span>,background:<span class="string">&#x27;#f50&#x27;</span>&#125;&#125;</span><span class="xml"><span class="tag"></span></span></span><br><span class="line"><span class="tag"><span class="xml">          <span class="attr">key</span>=<span class="string">&quot;key&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="xml">          <span class="attr">ref</span>=<span class="string">&quot;element&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="xml">          <span class="attr">refInFor</span></span></span></span><br><span class="line"><span class="tag"><span class="xml">          <span class="attr">slot</span>=<span class="string">&quot;slot&quot;</span>&gt;</span></span></span><br><span class="line"><span class="xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="xml">    )</span></span><br><span class="line"><span class="xml">&#125;</span></span><br></pre></td></tr></table></figure></li><li>注意：如果项目不是 JSX 强驱动，建议还是以模板 template 的方式为主，特殊场景（比如锚点标题）使用 Render 的 createElement 辅助。</li></ul></li></ul><h4 id="9-6-实战：使用-Render-函数开发可排序的表格组件。"><a href="#9-6-实战：使用-Render-函数开发可排序的表格组件。" class="headerlink" title="9.6 实战：使用 Render 函数开发可排序的表格组件。"></a>9.6 实战：使用 Render 函数开发可排序的表格组件。</h4></div><div><div><div style="text-align:center;color:#ccc;font-size:14px">-------------end-------------</div></div></div><footer class="post-footer"><div class="post-tags"><a href="/blog/tags/Web/" rel="tag"><i class="fa fa-tag"></i> Web</a> <a href="/blog/tags/Vue/" rel="tag"><i class="fa fa-tag"></i> Vue</a></div><div class="post-nav"><div class="post-nav-item"><a href="/blog/categories/Python/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1-3-%E6%95%B0%E6%8D%AE%E9%87%87%E9%9B%86/" rel="prev" title="1.3 数据采集"><i class="fa fa-chevron-left"></i> 1.3 数据采集</a></div><div class="post-nav-item"><a href="/blog/categories/%E6%9C%89%E9%81%93%E4%BA%91%E7%AC%94%E8%AE%B0-%E6%90%AC/%E9%85%8D%E7%BD%AE/vscode%E9%85%8D%E7%BD%AE/vscode%E9%82%A3%E4%BA%9B%E5%A5%BD%E7%94%A8%E7%9A%84%E6%8F%92%E4%BB%B6/" rel="next" title="vscode那些好用的插件">vscode那些好用的插件 <i class="fa fa-chevron-right"></i></a></div></div></footer></article></div><div class="comments"><script src="https://utteranc.es/client.js" repo="linxiaoki/comments" issue-term="pathname" theme="github-light" crossorigin="anonymous" async></script></div><script>window.addEventListener("tabs:register",()=>{let{activeClass:e}=CONFIG.comments;if(CONFIG.comments.storage&&(e=localStorage.getItem("comments_active")||e),e){let t=document.querySelector(`a[href="#comment-${e}"]`);t&&t.click()}}),CONFIG.comments.storage&&window.addEventListener("tabs:click",t=>{t.target.matches(".tabs-comment .tab-content .tab-pane")&&(t=t.target.classList[1],localStorage.setItem("comments_active",t))})</script></div><div class="toggle sidebar-toggle"><span class="toggle-line toggle-line-first"></span> <span class="toggle-line toggle-line-middle"></span> <span class="toggle-line toggle-line-last"></span></div><aside class="sidebar"><div class="sidebar-inner"><ul class="sidebar-nav motion-element"><li class="sidebar-nav-toc">文章目录</li><li class="sidebar-nav-overview">站点概览</li></ul><div class="post-toc-wrap sidebar-panel"><div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-4"><a class="nav-link" href="#9-1-%E4%BB%80%E4%B9%88%E6%98%AF-Virtrual-Dom"><span class="nav-number">1.</span> <span class="nav-text">9.1 什么是 Virtrual Dom</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#9-2-%E4%BB%80%E4%B9%88%E6%98%AF-Render-%E5%87%BD%E6%95%B0"><span class="nav-number">2.</span> <span class="nav-text">9.2 什么是 Render 函数</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E5%AE%9E%E7%8E%B0%E9%94%9A%E7%82%B9%E6%A0%87%E7%AD%BE"><span class="nav-number">2.1.</span> <span class="nav-text">实现锚点标签</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#9-3-reateElement-%E7%94%A8%E6%B3%95"><span class="nav-number">3.</span> <span class="nav-text">9.3 reateElement 用法</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#9-3-1-%E5%9F%BA%E6%9C%AC%E5%8F%82%E6%95%B0"><span class="nav-number">3.1.</span> <span class="nav-text">9.3.1 基本参数</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#9-3-2-%E7%BA%A6%E6%9D%9F"><span class="nav-number">3.2.</span> <span class="nav-text">9.3.2 约束</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#9-3-3-%E4%BD%BF%E7%94%A8-JavaScript-%E4%BB%A3%E6%9B%BF%E6%A8%A1%E6%9D%BF%E5%8A%9F%E8%83%BD"><span class="nav-number">3.3.</span> <span class="nav-text">9.3.3 使用 JavaScript 代替模板功能</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#9-4-%E5%87%BD%E6%95%B0%E5%8C%96%E7%BB%84%E4%BB%B6"><span class="nav-number">4.</span> <span class="nav-text">9.4 函数化组件</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#9-5-JavaScript-%E7%9A%84%E8%AF%AD%E6%B3%95%E6%89%A9%E5%B1%95%EF%BC%9AJSX"><span class="nav-number">5.</span> <span class="nav-text">9.5 JavaScript 的语法扩展：JSX</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#9-6-%E5%AE%9E%E6%88%98%EF%BC%9A%E4%BD%BF%E7%94%A8-Render-%E5%87%BD%E6%95%B0%E5%BC%80%E5%8F%91%E5%8F%AF%E6%8E%92%E5%BA%8F%E7%9A%84%E8%A1%A8%E6%A0%BC%E7%BB%84%E4%BB%B6%E3%80%82"><span class="nav-number">6.</span> <span class="nav-text">9.6 实战：使用 Render 函数开发可排序的表格组件。</span></a></li></ol></div></div><div class="site-overview-wrap sidebar-panel"><div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person"><img class="site-author-image" itemprop="image" alt="我的名字" src="/blog/images/avatar.gif"><p class="site-author-name" itemprop="name">我的名字</p><div class="site-description" itemprop="description">一起滚月球吧·</div></div><div class="site-state-wrap motion-element"><nav class="site-state"><div class="site-state-item site-state-posts"><a href="/blog/archives/"><span class="site-state-item-count">101</span> <span class="site-state-item-name">日志</span></a></div><div class="site-state-item site-state-categories"><a href="/blog/categories/"><span class="site-state-item-count">44</span> <span class="site-state-item-name">分类</span></a></div><div class="site-state-item site-state-tags"><a href="/blog/tags/"><span class="site-state-item-count">64</span> <span class="site-state-item-name">标签</span></a></div></nav></div><div class="links-of-author motion-element"><span class="links-of-author-item"><a href="https://github.com/linxiaoki" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;linxiaoki" rel="noopener" target="_blank"><i class="fa fa-fw fa-github"></i>GitHub</a></span></div></div><div class="back-to-top motion-element"><i class="fa fa-arrow-up"></i> <span>0%</span></div></div></aside><div id="sidebar-dimmer"></div></div></main><footer class="footer"><div class="footer-inner"><div class="copyright">&copy; <span itemprop="copyrightYear">2024</span> <span class="with-love"><i class="fa fa-user"></i> </span><span class="author" itemprop="copyrightHolder">我的名字</span> <span class="post-meta-divider">|</span> <span class="post-meta-item-icon"><i class="fa fa-area-chart"></i> </span><span title="站点总字数">221k</span> <span class="post-meta-divider">|</span> <span class="post-meta-item-icon"><i class="fa fa-coffee"></i> </span><span title="站点阅读时长">3:21</span></div></div></footer></div><script color="0,134,139" opacity="0.6" zindex="22" count="199" src="/js/src/canvas-nest-nomobile.min.js"></script><script src="/blog/lib/anime.min.js"></script><script src="//cdn.jsdelivr.net/gh/theme-next/theme-next-pjax@0/pjax.min.js"></script><script src="//cdn.jsdelivr.net/npm/medium-zoom@1/dist/medium-zoom.min.js"></script><script src="/blog/lib/velocity/velocity.min.js"></script><script src="/blog/lib/velocity/velocity.ui.min.js"></script><script src="/blog/js/utils.js"></script><script src="/blog/js/motion.js"></script><script src="/blog/js/schemes/muse.js"></script><script src="/blog/js/next-boot.js"></script><script>var pjax=new Pjax({selectors:["head title","#page-configurations",".content-wrap",".post-toc-wrap",".languages","#pjax"],switches:{".post-toc-wrap":Pjax.switches.innerHTML},analytics:!1,cacheBust:!1,scrollTo:!CONFIG.bookmark.enable});window.addEventListener("pjax:success",()=>{document.querySelectorAll("script[data-pjax], script#page-configurations, #pjax script").forEach(e=>{var t=e.text||e.textContent||e.innerHTML||"",a=e.parentNode;a.removeChild(e);var s=document.createElement("script");e.id&&(s.id=e.id),e.className&&(s.className=e.className),e.type&&(s.type=e.type),e.src&&(s.src=e.src,s.async=!1),void 0!==e.dataset.pjax&&(s.dataset.pjax=""),""!==t&&s.appendChild(document.createTextNode(t)),a.appendChild(s)}),NexT.boot.refresh(),CONFIG.motion.enable&&NexT.motion.integrator.init().add(NexT.motion.middleWares.subMenu).add(NexT.motion.middleWares.postList).bootstrap(),NexT.utils.updateSidebarPosition()})</script><script src="/blog/js/local-search.js"></script><div id="pjax"></div><script src="/blog/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({model:{jsonPath:"/blog/live2dw/assets/hijiki.model.json"},display:{position:"left",vOffset:-75,hOffset:10,width:200,height:385},mobile:!1,react:{opacity:.7},log:!1,pluginJsPath:"lib/",pluginModelPath:"assets/",pluginRootPath:"live2dw/",tagMode:!1})</script></body></html>